package mobi.daogu.powerstripcontroller.widget

import android.content.res.Resources
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.PixelFormat
import android.graphics.drawable.Drawable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import mobi.daogu.powerstripcontroller.R
import java.util.LinkedList


/**
 * @FileName: PowerStripStatusDrawable.kt
 * @Description:
 * @Author: Gene
 * @Email: gene.fang@ringcentral.com
 * @Date: 2024/11/18 17:02
 */
class PowerStripStatusDrawable(private val resource: Resources) : Drawable() {
    private var isActive = false
    private var interruptStatus = InterruptStatus.NONE
    private var alpha: Int = 1
    private val segments = LinkedList<Pair<Float, Float>>()

    fun updateStatus(isActive: Boolean, interruptStatus: InterruptStatus, turnOnTriggers: List<Int>, turnOffTriggers: List<Int>) {
        this.isActive = isActive
        this.interruptStatus = interruptStatus
        segments.clear()
        mergeTimeTriggerList(LinkedList(turnOnTriggers), LinkedList(turnOffTriggers)) { on, off ->
            segments.addLast(Pair((on - 12) * 7.5f, (off - 12) * 7.5f))
        }

        invalidateSelf()
    }

    override fun draw(canvas: Canvas) {
        val strokeWidth = 40f
        val gap = 10f

        val center = Pair(bounds.width() / 2f, bounds.height() / 2f)
        val radius = if (bounds.width() > bounds.height()) bounds.height() / 2f else bounds.width() / 2f

        // draw the online/offline status
        canvas.drawArcWithCenter(center.first, center.second, 0f, 360f, radius, android.graphics.Paint().apply {
            color = if (isActive) resource.getColor(R.color.color_online) else resource.getColor(R.color.color_offline)
            isAntiAlias = true
        })

        canvas.drawArcWithCenter(center.first, center.second, 0f, 360f, radius - gap, android.graphics.Paint().apply {
            color = when(interruptStatus) {
                InterruptStatus.TURN_ON -> Color.Yellow.toArgb()
                InterruptStatus.TURN_OFF -> Color.Gray.toArgb()
                else -> 0xffeeeeee.toInt()
            }
            isAntiAlias = true
        })

        canvas.drawArcWithCenter(center.first, center.second, 0f, 360f, radius - strokeWidth / 2 - gap, android.graphics.Paint().apply {
            color = 0xff222222.toInt()
            this.strokeWidth = strokeWidth
            style = android.graphics.Paint.Style.STROKE
            isAntiAlias = true
        })

        val activePainter = android.graphics.Paint().apply {
            color = resource.getColor(R.color.teal_200)
            this.strokeWidth = strokeWidth - gap
            style = android.graphics.Paint.Style.STROKE
            strokeCap = android.graphics.Paint.Cap.ROUND
            isAntiAlias = true
        }

        segments.forEach {(on, off) ->
            canvas.drawArcWithCenter(center.first, center.second, on, off - on, radius - strokeWidth / 2 - gap, activePainter)
        }

        val mainTimeMarkPainter = android.graphics.Paint().apply {
            color = Color.Black.toArgb()
            this.strokeWidth = gap
            style = android.graphics.Paint.Style.STROKE
            strokeCap = android.graphics.Paint.Cap.ROUND
            isAntiAlias = true
        }

        listOf(0f, 90f, 180f, 270f).forEach {
            canvas.drawArcWithCenter(center.first, center.second, it - 1f,  2f, radius - gap / 2, mainTimeMarkPainter)
        }

        val subTimeMarkPainter = android.graphics.Paint().apply {
            color = Color.Black.toArgb()
            this.strokeWidth = gap
            style = android.graphics.Paint.Style.STROKE
            strokeCap = android.graphics.Paint.Cap.ROUND
            isAntiAlias = true
        }

        listOf(30f, 60f, 120f, 150f, 210f, 240f, 300f, 330f).forEach {
            canvas.drawArcWithCenter(center.first, center.second, it - 0.2f,  0.4f, radius - gap / 2, subTimeMarkPainter)
        }
    }

    override fun setAlpha(alpha: Int) {
        this.alpha = alpha
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
    }

    override fun getOpacity(): Int {
        return PixelFormat.UNKNOWN
    }

    private fun mergeTimeTriggerList(listOn : LinkedList<Int>, listOff : LinkedList<Int>, action: (Int, Int) -> Unit) {
        if (listOn.isEmpty()) {
            return
        }

        while (listOff.first < listOn.first) {
            val off = listOff.removeFirst()
            listOff.addLast(off + 48)
        }

        val firstOn = listOn.first

        while (listOn.isNotEmpty() || listOff.isNotEmpty()) {
            if (listOff.isEmpty()) {
                action(listOn.first, firstOn + 48)
                return
            } else {
                if (listOff.first.smallerThan(listOn.firstOrNull())) {
                    // Ignore the off trigger
                    listOff.removeFirst()
                } else {
                    action(listOn.removeFirst(), listOff.removeFirst())
                }
            }
        }
    }

    private fun Int.smallerThan(another : Int?) : Boolean {
        return if (another == null) {
            true
        } else {
            this < another
        }
    }

    private fun Canvas.drawArcWithCenter(centerX: Float, centerY: Float, startAngle: Float, sweepAngle: Float, radius: Float, paint: android.graphics.Paint) {
        drawArc(centerX - radius, centerY - radius, centerX + radius, centerY + radius, startAngle, sweepAngle, false, paint)
    }

    companion object {
        enum class InterruptStatus {
            NONE,
            TURN_ON,
            TURN_OFF
        }
    }
}